package com.yami.shop.admin.controller;

import com.yami.shop.bean.model.Order;
import com.yami.shop.bean.model.OrderSettlement;
import com.yami.shop.common.util.Arith;
import com.yami.shop.security.model.AppConnect;
import com.yami.shop.security.service.AppConnectService;
import com.yami.shop.service.OrderService;
import com.yami.shop.service.OrderSettlementService;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@RestController
@RequestMapping("/admin/apply")
@Api(tags = "地址接口")
@AllArgsConstructor
public class AppletOrders {

    private OrderService orderService;

    private OrderSettlementService orderSettlementService;

    private AppConnectService appConnectService;

    /*
     * 微信：
     *    测试环境：http://58.247.0.18:29015/v1/netpay/wx/unified-order
     *    生产环境：https://api-mop.chinaums.com/v1/netpay/wx/unified-order
     * 支付宝：
     *   测试环境：http://58.247.0.18:29015/v1/netpay/trade/create
     *   生产环境：https://api-mop.chinaums.com/v1/netpay/trade/create
     *
     *  appid   10037e6f6823b20801682b6a5e5a0006
     *  appkey  1c4e3b16066244ae9b236a09e5b312e8
     *  mid：898201612345678
     *  tid：88880001
     * */
    static String appId = "8a81c1bf76674cf60177428a6dfd0160";
    static String appKey = "592df373c018457096b357a7e51a2761";
    static String authorization;

    public static void main(String[] args) throws Exception {
       // orders();
    }

    /**
     * 下单
     */
    @PostMapping("/appletOrders")
    public String  orders(@RequestBody Order order) throws Exception {

        Order order1 = orderService.getOrderByOrderNumber(order.getOrderNumber());
        /* post参数,格式:JSON */
        JSONObject json = new JSONObject();
        json.put("msgId", order.getOrderNumber());   // 消息Id,原样返回
        json.put("requestTimestamp", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));    // 报文请求时间
        json.put("merOrderId","30AQ"+order.getOrderNumber()); // 商户订单号
        json.put("srcReserve", "请求系统预留字段"); // 请求系统预留字段
        json.put("mid", "89842065812010F"); // 商户号
        json.put("tid", "51554485");    // 终端号
        json.put("instMid", "MINIDEFAULT"); // 业务类型
       // json.put("appId","wx264c91a49317177b");
        json.put("subappid","wx264c91a49317177b");
      //  json.put("subOpenId", "oWG8S5SBkX2hjBuOF1qOkDiuKGXk");
        if(order1!=null){
            String userId = order1.getUserId();
            AppConnect appConnect = appConnectService.getAppConnectByOrderNumber(userId);
            String bizUserId = appConnect.getBizUserId();
           json.put("subopenid", bizUserId);
        }
       // json.put("openId", "oWG8S5SBkX2hjBuOF1qOkDiuKGXk");
        json.put("attachedData", "商户附加数据"); //商户附加数据
        json.put("expireTime", DateFormatUtils.format(new Date().getTime() + 60 * 60 * 1000, "yyyy-MM-dd HH:mm:ss"));  // 订单过期时间,这里设置为一个小时

        if(order!=null) {
            Double actualTotal = order.getActualTotal();
         //   json.put("totalAmount", Arith.mul(actualTotal,100));      // 支付总金额
            json.put("totalAmount", actualTotal);
        }
        json.put("notifyUrl", "https://wx.xiaoerlangdang.com/notice/pay/callback");  // 支付结果通知地址
        json.put("returnUrl", "http://www.wfdsj.cn/cn/index.htm");  // 网页跳转地址
        json.put("tradeType", "MINI");  // 交易类型

        String url = "https://api-mop.chinaums.com/v1/netpay/wx/unified-order";
        String send = send(url, json.toString());

        //增加支付记录
        OrderSettlement previouslySettlement =  orderSettlementService.getSettlementByOrderNumber(order.getOrderNumber());
        OrderSettlement orderSettlement = new OrderSettlement();
        if(previouslySettlement==null) {
            orderSettlement.setOrderNumber(order.getOrderNumber());
            orderSettlement.setPayType(1);
            //处理支付金额
            // double actualMoney = Arith.div(amount,100);
            orderSettlement.setPayAmount(order1.getActualTotal());
            orderSettlement.setUserId(order1.getUserId());
            orderSettlement.setCreateTime(new Date());
            orderSettlement.setVersion(0);
            orderSettlement.setPayStatus(0);
            orderSettlement.setPayType(1);
            orderSettlementService.save(orderSettlement);
        }
        System.out.println("返回结果:\n" + send);
        return send;
    }


    /**
     * 退款接口
     */
    @PostMapping("/refund")
    public String  refund(Order order) throws Exception{
            String orderNumber = order.getOrderNumber();
            Order currentOrder = orderService.getByOrderNumber(orderNumber);
            OrderSettlement orderSettlement = orderSettlementService.getSettlementByOrderNumber(orderNumber);
            String payNo = null;
            if (orderSettlement != null) {
                payNo = orderSettlement.getPayNo();
            }
            /* post参数,格式:JSON */
            JSONObject json = new JSONObject();
            String timestamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            json.put("requestTimestamp", timestamp);
            StringBuffer buffer = new StringBuffer("30AQ");
            json.put("merOrderId", buffer.append(orderNumber).toString());

            json.put("mid", "89842065812010F");
            json.put("tid", "51554485");
            json.put("targetOrderId", payNo);
            //查询订单退款金额
            Double actualTotal = currentOrder.getActualTotal();
            json.put("refundAmount", Arith.mul(actualTotal, 100));
            String url = "https://api-mop.chinaums.com/v1/netpay/refund";
            String result = send(url, json.toString());
            System.out.println("收到的结果为"+result);
            JSONObject jsonObj = new JSONObject(result);
            String errCode = jsonObj.getString("errCode");
            if("SUCCESS".equals(errCode)){
                String a = orderService.refundState(order);
            }
            return "SUCCESS";

    }


    /**
     * 发送请求
     *
     * @param url    eg:http://58.247.0.18:29015/v1/netpay/trade/create
     * @return
     * @throws Exception
     */
    public static String send(String url, String entity) throws Exception {
        authorization = getOpenBodySig(appId, appKey, entity);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost httpPost = new HttpPost(url);
        httpPost.addHeader("Authorization", authorization);
        StringEntity se = new StringEntity(entity, "UTF-8");
        se.setContentType("application/json");
        httpPost.setEntity(se);
        CloseableHttpResponse response = httpClient.execute(httpPost);
        HttpEntity entity1 = response.getEntity();
        String resStr = null;
        if (entity1 != null) {
            resStr = EntityUtils.toString(entity1, "UTF-8");
        }
        httpClient.close();
        response.close();
        return resStr;
    }

    /**
     * open-body-sig方式获取到Authorization 的值
     *
     * @param appId  f0ec96ad2c3848b5b810e7aadf369e2f
     * @param appKey 775481e2556e4564985f5439a5e6a277
     * @param body   json字符串 String body = "{\"merchantCode\":\"123456789900081\",\"terminalCode\":\"00810001\",\"merchantOrderId\":\"20123333644493200\",\"transactionAmount\":\"1\",\"merchantRemark\":\"测试\",\"payMode\":\"CODE_SCAN\",\"payCode\":\"285668667587422761\",\"transactionCurrencyCode\":\"156\"}";
     * @return
     * @throws Exception
     */
    public static String getOpenBodySig(String appId, String appKey, String body) throws Exception {
        String timestamp = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());   // eg:20190227113148
        String nonce = UUID.randomUUID().toString().replace("-", ""); // eg:be46cd581c9f46ecbd71b9858311ea12
        byte[] data = body.getBytes("UTF-8");
        System.out.println("data:\n" + body);
        InputStream is = new ByteArrayInputStream(data);
        String bodyDigest = testSHA256(is); // eg:d60bc3aedeb853e2a11c0c096baaf19954dd9b752e48dea8e919e5fb29a42a8d
        System.out.println("bodyDigest:\n" + bodyDigest);
        String str1_C = appId + timestamp + nonce + bodyDigest; // eg:f0ec96ad2c3848b5b810e7aadf369e2f + 20190227113148 + be46cd581c9f46ecbd71b9858311ea12 + d60bc3aedeb853e2a11c0c096baaf19954dd9b752e48dea8e919e5fb29a42a8d

        System.out.println("str1_C:" + str1_C);

//        System.out.println("appKey_D:\n" + appKey);

        byte[] localSignature = hmacSHA256(str1_C.getBytes(), appKey.getBytes());

        String localSignatureStr = Base64.encodeBase64String(localSignature);   // Signature
        System.out.println("Authorization:\n" + "OPEN-BODY-SIG AppId=" + "\"" + appId + "\"" + ", Timestamp=" + "\"" + timestamp + "\"" + ", Nonce=" + "\"" + nonce + "\"" + ", Signature=" + "\"" + localSignatureStr + "\"\n");
        return ("OPEN-BODY-SIG AppId=" + "\"" + appId + "\"" + ", Timestamp=" + "\"" + timestamp + "\"" + ", Nonce=" + "\"" + nonce + "\"" + ", Signature=" + "\"" + localSignatureStr + "\"");
    }

    /**
     * 进行加密
     *
     * @param is
     * @return 加密后的结果
     */
    private static String testSHA256(InputStream is) {
        try {
//            System.out.println(is.hashCode());
            return DigestUtils.sha256Hex(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * @param data
     * @param key
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    public static byte[] hmacSHA256(byte[] data, byte[] key) throws NoSuchAlgorithmException, InvalidKeyException {
        String algorithm = "HmacSHA256";
        Mac mac = Mac.getInstance(algorithm);
        mac.init(new SecretKeySpec(key, algorithm));
        return mac.doFinal(data);
    }

    /**
     * 获取到订单号
     *
     * @return 订单号
     */
    public static String getMerchantOrderId() {
        return DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS") + RandomStringUtils.randomNumeric(7);
    }

}
